if (typeof(marlon) === 'undefined') marlon = {};
if (typeof(marlon.onlineproxy) === 'undefined') marlon.onlineproxy = {};

(function(ns) {
	function loadJQuery() {
		window.jQuery.noConflict();
		ns.jQuery = window.jQuery;
		delete window.jQuery;
	}
	loadJQuery();
	var $, jQuery;
	$ = jQuery = ns.jQuery;

	String.prototype.startsWith = function(s) {
		return this.indexOf(s) == 0;
	}

	// ==== page submit ====
	ns.sbmtProxy = function(form) {
		if (!form) {
			form = $('#p4y_topform')[0];
		}
		var url = form["url"].value;
		if (url.indexOf("http://") != 0 && url.indexOf("https://") != 0)
			url = "http://" + url;
		var param = { 'url': url };
		var seed = form["seed"].value;
		if (seed) {
			param["seed"] = seed;
		}
		document.location = "/p/" + ns.encode(param) + "/";
		return false;
	}


	function getUrlParams() {
		var url = window.location.toString();
		 //get the parameters
		 url.match(/\?(.+)$/);
		 var params = RegExp.$1;
		 // split up the query string and store in an associative array
		 var params = params.split("&");
		 var queryStringList = {};
		 
		 for (var i=0;i<params.length;i++) {
			 var tmp = params[i].split("=");
			 queryStringList[tmp[0]] = unescape(tmp[1]);
		 }
		 return queryStringList;
	}

	function isAbsUrl(url) {	
		return url.startsWith("http://") || url.startsWith("https://");
	}

	// return [protocol, netloc, path, query, fragment]
	function parseUrl(url) {
		var res = new Array();
		if (isAbsUrl(url)) {
			var colon = url.indexOf('://');
			var protocol = url.substring(0, colon);
			res[0] = protocol;
			var domainS = colon + 3;
			var slash = url.indexOf('/', domainS);
			if (slash != -1) {
				res[1] = url.substring(domainS, slash);
				url = url.substring(slash);
			} else {
				res[1] = url.substring(domainS);
				res[2] = res[3] = res[4] = '';
				return res;
			}
		} else {
			res[0] = '';
			res[1] = '';
		}
		var ques = url.indexOf('?');
		if (ques != -1) {
			res[2] = url.substring(0, ques);
			url = url.substring(ques+1);
		} else {
			res[2] = url.substring(0);
			res[3] = res[4] = '';
			return res;
		}
		var sharp = url.indexOf('#');
		if (sharp != -1) {
			res[3] = url.substring(0, sharp);
			res[4] = url.substring(sharp+1);
		} else {
			res[3] = url;
			res[4] = '';
		}
		return res;
	}

	function unparseUrl(parts) {
		var res = parts[0];
		if (!res) res += '://';		// protocol
		res += parts[1];			// netloc
		res += parts[2];			// path
		if (!parts[3])				// query
			res += '?' + parts[3];
		if (!parts[4])				// frag
			res += '#' + parts[4];
		return res;
	}

	function joinUrl(base, url) {
		if (isAbsUrl(url)) return url;
		if (!url) return base;
		if (url[0] != '/') { // relative path
			if (base[base.length-1] != '/') base += '/'
			return base += url;
		} else {		// absolute
			var parts = parseUrl(base);
			return parts[0] + '://' + parts[1] + url;
		}
	}

	// ==== encoding utils ====
	// constants
	CODE_LA = 'a'.charCodeAt(0);
	CODE_LZ = 'z'.charCodeAt(0);
	CODE_UA = 'A'.charCodeAt(0);
	CODE_UZ = 'Z'.charCodeAt(0);
	CODE_0 = '0'.charCodeAt(0);
	CODE_9 = '9'.charCodeAt(0);
	// base64 character set
	_keyStr = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_";

	// public method
	ns.encode = function(dict) {
		var seed = dict['$seed'];
		if (typeof(seed) !== 'undefined') {
			delete dict['$seed'];
		} else {
			seed = _random(1000);
			seed = _pad(seed, 3);
		}
		var str = '';
		for (var k in dict) {
			var v = dict[k];
			str += String.fromCharCode(k.length) + k;
			str += String.fromCharCode(v.length) + v;
		}
		return encode_str(str, seed);
	}
	// public method
	ns.decode = function(input) {
		var arr = decode_str(input);
		var seed = arr[0];
		var str = arr[1];
		var res = {};
		var i = 0;
		while (i < str.length) {
			var klen = str.charCodeAt(i++);
			var key = str.substring(i, i+klen);
			i += klen;
			var vlen = str.charCodeAt(i++);
			var value = str.substring(i, i+vlen);
			i += vlen;
			res[key] = value;
		}
		res['$seed'] = seed;
		return res;
	}

	// private methods
	function encode_str(input, seed) {
		input = _utf8_encode(input);
		input = _b64encode(input);
		
		return '0' /*version number*/ + seed + _rot(input, _parseInt(seed));
	}

	function decode_str(input) {
		var seed = input.substring(1, 4);
		shift = _parseInt(seed);
		var text = input.substring(4);
		text = _rot(text, -shift);
		var text = _b64decode(text);
		return [seed, _utf8_decode(text)];
	}

	function _parseInt(str) {
		str = str.replace(/^0*/, '');
		if (!str) return 0;
		return parseInt(str);
	}

	function _rot(input, n) {
		var res = ''
		var n_26 = n % 26;
		if (n_26 < 0) n_26 += 26;
		var n_10 = n % 10;
		if (n_10 < 0) n_10 += 10;
		for (var i = 0; i < input.length; i++) {
			var c = input.charCodeAt(i);
			if (c >= CODE_LA && c <= CODE_LZ) {
				c += n_26;
				if (c > CODE_LZ) {
					c = CODE_LA + (c - CODE_LZ - 1);
				}
			} else if (c >= CODE_UA && c <= CODE_UZ) {
				c += n_26;
				if (c > CODE_UZ) {
					c = CODE_UA + (c - CODE_UZ - 1);
				}
			} else if (c >= CODE_0 && c <= CODE_9) {
				c += n_10;
				if (c > CODE_9) {
					c = CODE_0 + (c - CODE_9 - 1)
				}
			}
			res += String.fromCharCode(c);
		}
		return res;
	}

	function _pad(num, sz) {
		var str = '' + num;
		for (var i = str.length; i < sz; i++) {
			str = '0' + str;
		}
		return str;
	}

	// generate a random number bewteen 0 and n(exclusive)
	function _random(n) {
		return Math.floor(Math.random()*n);
	}

	function _b64encode(input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
			_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
 
		}
		return output;
	}
 
	function _b64decode(input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		//input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = _keyStr.indexOf(input.charAt(i++));
			enc2 = _keyStr.indexOf(input.charAt(i++));
			enc3 = _keyStr.indexOf(input.charAt(i++));
			enc4 = _keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}

		return output;
	}
 
	// private method for UTF-8 encoding
	function _utf8_encode(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
		}
 
		return utftext;
	}
 
	// private method for UTF-8 decoding
	function _utf8_decode(utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
		return string;
	}
})(marlon.onlineproxy);
